package cn.ygh.bbo.system.web.controller;

import cn.ygh.bbo.common.exception.TipException;
import cn.ygh.bbo.framerwork.core.ResultAjax;
import cn.ygh.bbo.system.bean.Admin;
import cn.ygh.bbo.system.bean.AdminRole;
import cn.ygh.bbo.system.bean.Role;
import cn.ygh.bbo.system.service.AdminRoleService;
import cn.ygh.bbo.system.service.AdminService;
import cn.ygh.bbo.system.service.CodeService;
import cn.ygh.bbo.system.service.RoleService;
import com.google.code.kaptcha.Constants;
import com.google.code.kaptcha.Producer;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.util.Date;
import java.util.UUID;

/**
 * @author ygh
 * @Desc 公共接口api
 * @date 2019/10/12
 */
@RestController
@RequestMapping("/pub")
public class PubController {

    /**
     * 默认关闭验证码请求
     */
    private final static Boolean USECAPTCHA = true;

    @Autowired
    AdminService adminService;

    @Autowired
    RoleService roleService;

    @Autowired
    AdminRoleService adminRoleService;

    @Autowired
    Producer producer;

    @Autowired
    CodeService codeService;

    /**
     * 登陆接口
     *
     * @param admin
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value = "/login", method = RequestMethod.GET)
    public ResultAjax loginByUsername(Admin admin, HttpServletRequest request, HttpServletResponse response
            , @RequestParam(required = false, defaultValue = "false") Boolean remeberMe, String codeToken, String code) {
        //账号密码验证
        if (StringUtils.isBlank(admin.getUsername()) || StringUtils.isBlank(admin.getPassword())) {
            return ResultAjax.fail("账号密码不能为空");
        }
        //验证码验证
        if (USECAPTCHA) {
            if (StringUtils.isBlank(codeToken)) {
                throw new TipException("验证码错误");
            }
            if (StringUtils.isBlank(code)) {
                throw new TipException("请输入验证码");
            }
            String c = codeService.getCode(codeToken);
            if (StringUtils.isBlank(c) || !c.equals(code)) {
                throw new TipException("验证码错误");
            }
            //删除验证码 如果通过的话
            codeService.removeCode(codeToken);
        }
        //shiro登陆
        UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken();
        usernamePasswordToken.setUsername(admin.getUsername());
        usernamePasswordToken.setPassword(admin.getPassword().toCharArray());
        usernamePasswordToken.setRememberMe(remeberMe);
        Subject subject = SecurityUtils.getSubject();
        subject.login(usernamePasswordToken);
        //返回登陆凭证
        return ResultAjax.success(subject.getSession().getId());

    }


    /**
     * 初始化超管账号
     *
     * @param request
     * @param response
     * @param model
     * @return
     */
    @RequestMapping(value = "/initAdmin", method = RequestMethod.GET)
    public ResultAjax initAdmin(HttpServletRequest request, HttpServletResponse response, ModelMap model, String password) throws Exception {
        if (!"111111".equals(password)) {
            return ResultAjax.fail("初始化密码错误");
        }
        //超管账号初始化
        Admin admin = adminService.getByUsername("admin");
        if (admin == null) {
            admin = new Admin(
                    "admin" //用户名
                    , password //密码
                    , "超管" //姓名
                    , "111111" //手机号
                    , 0 //部门序号
                    , null //创建时间
                    , null //更新时间
                    , 0 //状态
            );
            adminService.save(admin);
        }
        //超管角色初始化
        Role role = roleService.getByName("Admin");
        if (role == null) {
            role = new Role(
                    0 //父权限序号
                    , "Admin" //部门名
                    , "超管"//备注
                    , 0 //等级
                    , new Date() //创建时间
            );
            roleService.save(role);
        }
        //管理员与角色关联
        AdminRole adminRole = adminRoleService.findByRoleIdAndAdminId(role.getId(), admin.getId());
        if (adminRole == null) {
            adminRole = new AdminRole(
                    role.getId() //管理员ID
                    , admin.getId() //角色ID
            );
            adminRoleService.save(adminRole);
        }
        return ResultAjax.success();
    }

    /**
     * 生成验证码
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/code", method = RequestMethod.GET)
    public ResultAjax code(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String codeToken=UUID.randomUUID().toString();
        String code=producer.createText();
        codeService.saveCode(codeToken, code);
        return ResultAjax.success(codeToken);
    }

    /**
     * 验证码图片接口
     *
     * @param request
     * @param response
     * @throws Exception
     */
    @RequestMapping(value = "/kaptchaImage", method = RequestMethod.GET)
    public void getKaptchaImage(HttpServletRequest request, HttpServletResponse response, String codeToken) throws Exception {
        String code = codeService.getCode(codeToken);
        if (StringUtils.isBlank(code)) {
            throw new TipException("验证码异常");
        }
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        // create the image with the text
        BufferedImage bi = producer.createImage(code);
        ServletOutputStream out = response.getOutputStream();
        // write the data out
        ImageIO.write(bi, "jpg", out);
        try {
            out.flush();
        } finally {
            out.close();
        }
    }
}
